package com.zf.jetcache.service;

import com.alicp.jetcache.*;
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.support.Fastjson2KeyConvertor;
import com.alicp.jetcache.support.JavaValueDecoder;
import com.alicp.jetcache.support.JavaValueEncoder;
import com.alicp.jetcache.template.QuickConfig;
import com.zf.jetcache.entity.Product;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.HashSet;
import java.util.List;

/**
 * 非注解操作
 */
@Service
@Slf4j
public class ProductServiceNoAnno {

    // 缓存的名称，缓存名称对应的缓存如果不存在会自动创建缓存
    public static final String CACHE_NAME = "productCache:";

    public static final String DEFAULT_AREA = "default";
    public static final String OTHER_AREA = "other";

    /**
     * 可以注入 CacheManager 手动操作缓存，在jetcache 2.7 版本CreateCache注解已经废弃，可以使用CacheManager.getOrCreateCache(QuickConfig) 自定义缓存
     * 详见：https://github.com/alibaba/jetcache/blob/master/docs/CN/CreateCache.md
     */
    @Autowired
    private CacheManager cacheManager;

    /**
     * 获取缓存
     */
    public Cache<Object, Object> getCache() {
        // 获取缓存，如果缓存不存在则返回 null, 可能造成空指针异常，不推荐
        // return cacheManager.getCache(OTHER_AREA, CACHE_NAME);

        // 使用自定义配置 创建 Cache
        QuickConfig quickConfig = QuickConfig.newBuilder(OTHER_AREA, CACHE_NAME)
                .useAreaInPrefix(true)
                .cacheNullValue(true)
                .cacheType(CacheType.BOTH)
                .expire(Duration.ofSeconds(60L))
                .keyConvertor(Fastjson2KeyConvertor.INSTANCE)
                .valueEncoder(JavaValueEncoder.INSTANCE)
                .valueDecoder(JavaValueDecoder.INSTANCE)
                .syncLocal(false)
                .build();

        // 存在就返回，否则就创建
        return cacheManager.getOrCreateCache(quickConfig);
    }

    public Product getById(Long id) {

        CacheGetResult<Object> cacheGetResult = getCache().GET(id);
        if (cacheGetResult.getResultCode() == CacheResultCode.SUCCESS) {
            return (Product) cacheGetResult.getValue();
        }
        CacheResult put = getCache().PUT(id, null);
        if (CacheResultCode.SUCCESS != put.getResultCode()) {
            log.error("get方法写入缓存失败");
        }
        log.info("进入了get方法，数据：{}", id);
        return null;
    }

    public Product save(Product product) {
        CacheResult put = getCache().PUT(product.getId(), product);
        if (CacheResultCode.SUCCESS != put.getResultCode()) {
            log.error("save方法写入缓存失败");
        }
        log.info("进入了save方法，数据：{}", product);
        return product;
    }

    public Product update(Product product) {
        CacheResult put = getCache().PUT(product.getId(), product);
        if (CacheResultCode.SUCCESS != put.getResultCode()) {
            log.error("update方法更新缓存失败");
        }
        log.info("进入了update方法，数据：{}", product);
        return product;
    }

    public void delete(Long id) {
        CacheResult remove = getCache().REMOVE(id);
        if (CacheResultCode.SUCCESS != remove.getResultCode()) {
            log.error("delete方法移除缓存失败");
        }
        log.info("进入了delete方法，数据：{}", id);
    }


    public void deleteAll(List<Long> idList) {
        HashSet<Long> idSet = new HashSet<>(idList);
        CacheResult remove = getCache().REMOVE_ALL(idSet);
        if (CacheResultCode.SUCCESS != remove.getResultCode()) {
            log.error("deleteAll方法移除缓存失败");
        }
        log.info("进入了deleteAll方法，数据：{}", idList);
    }
}
